﻿using Microsoft.WindowsAzure.MediaServices.Client;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MediaAdmin.Controllers
{
    [Authorize]
    public partial class JobController : BaseController
    {

        public ActionResult Index()
        {
            var jobs = Context.Jobs.ToList();
            //jobs.ForEach(x => x.Delete());
            var model = ModelMapper.Map<List<IJob>, List<JobController.JobSummaryShortly>>(jobs).OrderBy(x => x.EndTime);
            return View(model);
        }


        public ActionResult Details(string id)
        {
            var job = Context.Jobs.Where(x => x.Id == id).SingleOrDefault();
            var model = ModelMapper.Map<IJob, JobController.JobSummary>(job);
            return View(model);
        }

        public ActionResult Create()
        {
            var assets = Context.Assets.ToList();
            var assums = ModelMapper.Map<List<IAsset>, List<JobController.AssetSummary>>(assets);
            var di = new DirectoryInfo(HttpContext.Server.MapPath("~/App_Data/presets/"));
            var presets = di.GetFiles().Select(x => x.Name);
            return View(new CreateJobModel() { AssetList = assums, Presets = presets.ToList() });
        }

        [HttpPost]
        public ActionResult Create(CreateJobModel model)
        {
            //if(model.PerformHLS && !(model.PerformSmooth || model.PerformEncoding))
            //{
            //    ModelState.AddModelError("links", "hls without smooth is not available");
            //    return View(model);
            //}

            try
            {
                var job = Context.Jobs.Create(model.Name);
                var asset = Context.Assets.Where(x => x.Id == model.AssetId).SingleOrDefault();

                var input = asset;

                if (model.PerformEncoding)
                {
                    var preset = System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/App_Data/presets/" + model.EncodingPresetName));
                    input = AttachTask(job, input, preset, "encoding task for " + model.Name, "Windows Azure Media Encoder");
                }

                if (model.PerformSmooth)
                {
                    var preset = System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/App_Data/presets/" + model.SmoothPresetName));
                    input = AttachTask(job, input, preset, "smooth task for " + model.Name, "MP4 to Smooth Streams Task");
                }

                if (model.PerformHLS)
                {
                    var preset = System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/App_Data/presets/" + model.HLSPresetName));
                    input = AttachTask(job, input, preset, "hls task for " + model.Name, "Smooth Streams to HLS Task");
                    if(model.DecryptHLS)
                        input = Decrypt(job, input);
                }

                if (model.PerformThumbnailing)
                {
                    var preset = System.IO.File.ReadAllText(HttpContext.Server.MapPath("~/App_Data/presets/" + model.ThumbnailPresetName));
                    var output = AttachTask(job, asset, preset, "thumbnailing task for " + model.Name, "Windows Azure Media Encoder");
                    Decrypt(job, output);
                }

                job.Submit();

                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }

        private IAsset Decrypt(IJob job, IAsset input)
        {
            var q = from p in Context.MediaProcessors
                    where p.Name == "Storage Decryption"
                    select p;

            ITask task = job.Tasks.AddNew("decrypt task", q.SingleOrDefault(), String.Empty, TaskCreationOptions.None);
            task.InputMediaAssets.Add(input);
            var output = task.OutputMediaAssets.AddNew("Clear" + input.Name, true, AssetCreationOptions.None);
            return output;
        }


        private IAsset AttachTask(IJob job, IAsset input, string preset, string taskname, string processorName)
        {
            var q = from p in Context.MediaProcessors
                    where p.Name == processorName
                    select p;

            IMediaProcessor processor = q.FirstOrDefault<IMediaProcessor>();
            if (processor == null)
            {
                throw new Exception("media processor not found");
            }

            ITask task = job.Tasks.AddNew(taskname, processor, preset, TaskCreationOptions.None);
            task.InputMediaAssets.Add(input);
            IAsset taskOutputAsset = task.OutputMediaAssets.AddNew(string.Format("{0} output", taskname), true);

            return taskOutputAsset;
        }

        public ActionResult Delete(string id)
        {
            var job = Context.Jobs.Where(x => x.Id == id).SingleOrDefault();
            return View(new DeleteModel() { Id = id, Name = job.Name });
        }

        [HttpPost]
        public ActionResult Delete(DeleteModel model)
        {
            try
            {
                var job = Context.Jobs.Where(x => x.Id == model.Id).SingleOrDefault();
                job.Delete();
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }
    }
}
